R u Ready? HS2025 | Psychologie der Digitalisierung - Einheit 8

Sandra Grinschgl, Aaron Friedli, Lars Schilling

R u Ready? Reproduzierbare Datenaufbereitung und -analyse mit R

HS 2025


LV-Leitung: Dr. Sandra Grinschgl / MSc. Aaron Friedli
Tutor: BSc. Lars Schilling


8. Einheit, 05.11.2025

Heute:

Codebook:

  • Metadata

  • Response Labels

Stellt sicher dass diese Punkte auch ausgefüllt sind für die Schlussabgabe.

Nachtrag: row.names = FALSE

row.names = FALSE sorgt dafür, dass keine neue Spalte eingefügt wird, die alle Zeilen durchnummeriert (also einen zusätzlichen „Spaltennamen“ erzeugt).

Wenn ihr in eurem dat_full als erste Spalte eine solche Bezeichnung wie „…1“ findet, habt ihr dat_full wahrscheinlich ohne das Argument row.names = FALSE abgespeichert. Das ist nicht weiter schlimm, sollte aber bereinigt werden (z. B. mit select()).

write.csv(dat_full, "data/raw/dat_full_rownames.csv")
dat_full_rownames[1:5, 1:3]
# A tibble: 5 × 3
   ...1  code question1
  <dbl> <dbl>     <dbl>
1     1     1         2
2     2     2         3
3     3     3         2
4     4     4         1
5     5     5         3

Entfernen mit select()

dat_full_rownames <- dat_full_rownames |> 
  select(-"...1")

Nachtrag: write.csv2()

Die beiden Funktionen unterscheiden sich nur in den verwendeten Trennzeichen:

  • write.csv() nutzt Kommas als Spaltentrenner und Punkte als Dezimaltrennzeichen.

  • write.csv2() nutzt Semikolons als Spaltentrenner und Kommas als Dezimaltrennzeichen.

Bottom Line: Nutzt write.csv() – sonst kann es passieren, dass Werte mit Nachkommastellen nicht korrekt von R interpretiert werden.

Nachtrag: select()

Kann nicht verwendet werden, um Rows/Zeilen auszuwählen! Auswahl von Spalten!

Aber: Dafür gibt es Funktionen wie slice() – allerdings wollen wir in der Regel keine Zeilen ohne logisches Kriterium auswählen.
👉 filter() ist deshalb meist die bessere Option.

penguins |>
  select(bill_depth_mm) |>
  slice(10) 
# A tibble: 1 × 1
  bill_depth_mm
          <dbl>
1          20.2

Kombination select() und full_join() - Beispiel

penguins <- palmerpenguins::penguins
penguins <- penguins |>
  mutate(id = row_number())

penguins2 <- palmerpenguins::penguins
penguins2 <- penguins2 |>
  mutate(id = row_number())
dat_final <- penguins |>
  select(id, species, year) |>
  full_join(
    penguins2 |> select(id, island, sex),
    by = "id"
  )

arrange()

Nützlich, um höchste und niedrigste Werte einzusehen – zum Beispiel, um eine Rangliste zu erstellen.



penguins |> 
  arrange(bill_depth_mm)
# A tibble: 344 × 9
   species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
   <fct>   <fct>           <dbl>         <dbl>             <int>       <int>
 1 Gentoo  Biscoe           42.9          13.1               215        5000
 2 Gentoo  Biscoe           46.1          13.2               211        4500
 3 Gentoo  Biscoe           44.9          13.3               213        5100
 4 Gentoo  Biscoe           43.3          13.4               209        4400
 5 Gentoo  Biscoe           46.5          13.5               210        4550
 6 Gentoo  Biscoe           42            13.5               210        4150
 7 Gentoo  Biscoe           44            13.6               208        4350
 8 Gentoo  Biscoe           40.9          13.7               214        4650
 9 Gentoo  Biscoe           45.5          13.7               214        4650
10 Gentoo  Biscoe           42.6          13.7               213        4950
# ℹ 334 more rows
# ℹ 3 more variables: sex <fct>, year <int>, id <int>

relocate()

Wird genutzt, um Spalten zu verschieben – nützlich, um den Datensatz übersichtlicher zu gestalten, etwa indem man wichtige Variablen (z. B. ID, Gruppe) an den Anfang stellt.



penguins |> relocate(bill_depth_mm, .before = island)
# A tibble: 344 × 9
   species bill_depth_mm island    bill_length_mm flipper_length_mm body_mass_g
   <fct>           <dbl> <fct>              <dbl>             <int>       <int>
 1 Adelie           18.7 Torgersen           39.1               181        3750
 2 Adelie           17.4 Torgersen           39.5               186        3800
 3 Adelie           18   Torgersen           40.3               195        3250
 4 Adelie           NA   Torgersen           NA                  NA          NA
 5 Adelie           19.3 Torgersen           36.7               193        3450
 6 Adelie           20.6 Torgersen           39.3               190        3650
 7 Adelie           17.8 Torgersen           38.9               181        3625
 8 Adelie           19.6 Torgersen           39.2               195        4675
 9 Adelie           18.1 Torgersen           34.1               193        3475
10 Adelie           20.2 Torgersen           42                 190        4250
# ℹ 334 more rows
# ℹ 3 more variables: sex <fct>, year <int>, id <int>

Fehlende Werte

Wieso müssen wir überhaupt fehlende Werte behandeln?

  • Viele Funktionen in R funktionieren nur mit vollständigen Datensätzen.

  • Kennwerte wie Mittelwerte oder Standardabweichungen können nicht berechnet werden, wenn fehlende Werte enthalten sind.

  • Fehlende Werte können Ergebnisse verzerren, insbesondere wenn sie nicht zufällig fehlen.

Umgang mit fehlenden Werten:

  • Finden / Identifizieren!

  • Nachvollziehen

  • Handling - abhängig von eurem Studiendesign und Fragestellungen

Diverse Formen von Fehlenden Werten

  • NA (R-typische Kennzeichnung für Not Available)

  • 999 oder -999 (häufig manuell gesetzte Platzhalter)

  • leere Zellen ("")

  • NULL (in manchen Programmiersprachen, aber in R selten in Datensätzen verwendet)

Finden und identifizieren von fehlenden Werten

Diverse Ansätze - Konkrete Übungen in den Hands On Übungen.

table(is.na(penguins))

FALSE  TRUE 
 3077    19 



colSums(is.na(penguins))
          species            island    bill_length_mm     bill_depth_mm 
                0                 0                 2                 2 
flipper_length_mm       body_mass_g               sex              year 
                2                 2                11                 0 
               id 
                0 

Fortgeschritten: Nachvollziehen!



  • Missing Completely at Random (MCAR): Fehlende Werte entstehen rein zufällig und stehen in keinem Zusammenhang mit anderen Daten.

  • Missing at Random (MAR): Fehlende Werte hängen mit beobachteten, aber nicht mit den fehlenden Variablen selbst zusammen.

  • Missing Not at Random (MNAR): Fehlende Werte stehen in direktem Zusammenhang mit den nicht beobachteten (fehlenden) Werten selbst.

Mögliche Ansätze um mit Missings umzugehen:

Fehlende Werte entfernen
Achtung: Je nach Analysemethode kann bereits ein einziger fehlender Wert dazu führen, dass eine ganze Versuchsperson aus der Analyse ausgeschlossen wird!



Fehlende Werte imputieren
Das bedeutet, fehlende Werte durch geschätzte Werte zu ersetzen (z. B. Mittelwert, Regression, Multiple Imputation).


→ Das üben wir nicht in diesem Seminar.

Fehlende Werte bei Berechnungen beachten

  • Viele R-Funktionen können fehlende Werte automatisch ausschliessen, z. B. mit na.rm = TRUE



x <- c(1, NA)

mean(x, na.rm = FALSE)   # fehlende Werte werden in Berechnung  miteinbezogen, ergibt NA als Mittelwert; default Einstellung
[1] NA
mean(x, na.rm = TRUE)    #fehlende Werte werden ausgeschlossen, ergibt 1 als Mittelwert
[1] 1

Skalenberechnung

Damit wir unsere Analysen sinnvoll durchführen können, müssen wir oft Skalen berechnen, also mehrere Items zu einem Gesamtwert zusammenfassen.



Schritte:

  1. Transformation der Antwortformate (z. B. von „Trifft häufig zu“ zu numerischen Werten).


  2. Beachtung von Reverse-Codierungen (z. B. beim Konstrukt Gewissenhaftigkeit: Item „Ich bin bequem, neige zur Faulheit“ muss umgepolt werden).


  3. Berechnung der Skalenwerte (z. B. durch Mittelwertbildung der entsprechenden Items).

Beispiele Berechnung von Skalenwerten

  • Einfache Variante


dat_full <- dat_full |> 
  mutate(mmq_mean = (question1 + question2 + question3 + question4 + question5 + question6 + question7 + question8 + question9 + question10 + question11 + question12 + question13 + question14 + question15 + question16 + question17 + question18)/18)
  • Sparsamerer Varianten: Dplyr Funktion verwenden um z.B. nicht alle Variablen auszuschreiben
#Sparsamere Alternative:

dat_full <- dat_full |> 
  mutate(mmq_mean = rowMeans(select(dat_full, starts_with("question")),
                             na.rm = TRUE))

#Sparsamere Alternative:

dat_full <- dat_full |>
  mutate(mmq_mean = rowMeans(across(question1:question18), na.rm = TRUE))

#Sparsamere Alternative:

dat_full <- dat_full %>%
  rowwise() %>%
  mutate(mmq_mean3 = mean(c_across(starts_with("question")), na.rm = TRUE))

Heute haben wir:

…Fehlende Werte und mögliche Umgangsformen angeschaut

… Skalenberechnung angeschaut

Congrats you mastered dplyr!!


Bis nächstes Mal

  • Hausübung 1 - Abgabe bis Freitag 07.11.2025 via Ilias (Ordner: Abgaben)

  • Peer-Feedback bis nächsten Mittwoch 12.11.2025

    • Direkte Kommentierung des Quartoskripts

    • Kurze Zusammenfassung im Forum (Ordner: EH8)!

  • Hands On Block 4 fertigstellen